<template>
  <div v-loading="loading" style="border: 1px solid #ccc; margin-top: 10px">
    <Toolbar class="bottom" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
    <Editor
      :style="{ height: height }"
      class="editor"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
    />
  </div>
</template>

<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'
import { IEditorConfig } from '@wangeditor/editor'
import { onBeforeUnmount, shallowRef } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'

import { uploadUrlOss } from '~/api'
import { TOKEN, VERSION } from '~/utils/const'

type InsertFnType = (url: string, alt: string, href: string) => void

// usage <sys-rich-text v-model="html" :default-html="initVal" :loading="loading" />

const props = defineProps({
  /**
   * 编辑器高度，默认300px
   */
  height: { type: String, default: '300px' },
  /**
   * 编辑器的默认值
   */
  defaultHtml: { type: String, default: '' },
  /**
   * 编辑器加载状态（实际类型为Ref<Boolean>），通常结合接口请求使用，用于数据未请求回来时的等待
   */
  loading: { type: Boolean, default: false },
  /**
   * v-model
   */
  modelValue: { type: String, default: null }
})

const emit = defineEmits(['update:modelValue'])

const mode = 'simple'
const toolbarConfig = {}

// 初始化 MENU_CONF 属性
const editorConfig: Partial<IEditorConfig> = {
  placeholder: '请输入内容...',
  MENU_CONF: {
    uploadImage: {
      server: uploadUrlOss,
      fieldName: 'file',
      maxFileSize: 1 * 1024 * 1024, // 1M
      allowedFileTypes: ['image/*'],
      meta: { type: '2' },
      headers: {
        Authorization: localStorage.getItem(TOKEN) || '',
        'X-Requested-With': 'XMLHttpRequest',
        version: VERSION,
        Platform: 'console'
      },
      customInsert(res: ResObj<string>, insertFn: InsertFnType) {
        if (res.code == 200) {
          insertFn(res.data + '/detail', '', res.data)
        } else {
          ElMessage.error('图片上传失败')
        }
      }
    }
  }
}

const valueHtml = ref('')

watchEffect(() => (valueHtml.value = props.defaultHtml))
watch(valueHtml, () => emit('update:modelValue', valueHtml.value))

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()

// 记录 editor 实例，重要！
const handleCreated = (editor: any) => (editorRef.value = editor)

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => editorRef.value?.destroy())
</script>

<style lang="scss" scoped>
.bottom {
  border-bottom: 1px solid var(--w-e-toolbar-border-color);
}
.editor {
  overflow-y: hidden;
}
</style>
